package base_validate

import (
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go-likaladi-shop/common/base_global"
	"go-likaladi-shop/common/base_util"
	"go.uber.org/zap"
	"net/http"
	"strings"
)

// ValidateReqParam 用于校验请求参数，并进行错误处理
// param: 需要绑定的参数结构体
// c: Gin 上下文对象，用于获取请求信息和返回响应
// 返回值: 如果参数解析成功且通过验证，返回 true，否则返回 false
func ValidateReqParam(param any, c *gin.Context) bool {
	// 1. 绑定请求参数到 param 结构体
	err := c.ShouldBind(param)

	if err != nil {
		// 2. 判断错误是否为 Validator 参数校验错误
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			// 3. 如果错误不是参数校验错误（例如 JSON 解析错误），记录错误日志并返回通用错误信息
			zap.S().Errorw("参数校验异常", "errorMsg", err.Error())
			base_util.RespCodeError(http.StatusBadRequest, "参数校验异常", c)
		} else {
			// 4. 如果是参数校验错误，则格式化错误信息，并返回给客户端
			errorMsg := formatValidateError2(errs.Translate(base_global.Trans))
			base_util.RespCodeError(http.StatusBadRequest, errorMsg, c)
		}
		return false // 解析或校验失败
	}

	return true // 解析与验证成功
}

// formatValidateError 格式化参数校验错误信息
// fields: 经过翻译的错误信息 Map（字段名 -> 错误信息）
// 返回值: 处理后的错误信息 Map，移除结构体名称前缀，仅保留字段名
func formatValidateError(fields map[string]string) map[string]string {
	rsp := map[string]string{}
	for field, err := range fields {
		// 1. `field` 格式为 "结构体名称.字段名"，如 "User.Username"
		// 2. 通过 strings.Index(field, ".") 找到 `.` 的位置，取 `.` 后面的部分作为字段名
		rsp[field[strings.Index(field, ".")+1:]] = err
		break
	}
	return rsp
}

func formatValidateError2(fields map[string]string) string {
	for _, err := range fields {
		// 1. `field` 格式为 "结构体名称.字段名"，如 "User.Username"
		// 2. 通过 strings.Index(field, ".") 找到 `.` 的位置，取 `.` 后面的部分作为字段名
		return err
	}
	return ""
}
